package com.swak.utils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.ToIntFunction;
import java.util.stream.Collectors;

import com.swak.utils.time.DateTimes;

/**
 * Lambdas 语法;
 * 
 * @author 618lf
 */
public class Lambdas {

	/**
	 * 求和
	 * 
	 * @param <T>
	 * @param items
	 * @param classifier
	 * @return
	 */
	public static <T> Integer sumToInt(List<T> items, ToIntFunction<T> classifier) {
		return items.stream().mapToInt(classifier).sum();
	}

	/**
	 * 分组
	 * 
	 * @param <C>
	 * @param <T>
	 * @param items
	 * @param classifier
	 * @return
	 */
	public static <C, T> Map<C, List<T>> group(List<T> items, Function<T, C> classifier) {
		return items.stream().collect(Collectors.groupingBy(classifier));
	}

	/**
	 * 过滤后分组
	 * 
	 * @param <C>
	 * @param <T>
	 * @param items
	 * @param predicate
	 * @param classifier
	 * @return
	 */
	public static <C, T> Map<C, List<T>> group(List<T> items, Predicate<T> predicate, Function<T, C> classifier) {
		return items.stream().filter(predicate).collect(Collectors.groupingBy(classifier));
	}
	
	/**
	 * 删除
	 * 
	 * @param <T>
	 * @param items
	 * @param predicate
	 */
	public static <T> boolean removeIf(List<T> items, Predicate<T> predicate) {
		return items.removeIf(predicate);
	}

	/**
	 * 查找第一个
	 * 
	 * @param <T>
	 * @param items
	 * @param predicate
	 * @return
	 */
	public static <T> T find(List<T> items, Predicate<T> predicate) {
		return items.stream().filter(predicate).findFirst().orElse(null);
	}

	/**
	 * 过滤
	 * 
	 * @param <T>
	 * @param items
	 * @param predicate
	 * @return
	 */
	public static <T> List<T> filter(List<T> items, Predicate<T> predicate) {
		return items.stream().filter(predicate).toList();
	}

	/**
	 * 查找第一个
	 * 
	 * @param <T>
	 * @param items
	 * @param predicate
	 * @return
	 */
	public static <T> boolean some(List<T> items, Predicate<T> predicate) {
		return items.stream().filter(predicate).findFirst().orElse(null) != null;
	}

	/**
	 * 转换
	 * 
	 * @param <T>
	 * @param items
	 * @param classifier
	 * @return
	 */
	public static <T, R> List<R> map(List<T> items, Function<T, R> classifier) {
		return items.stream().map(classifier).toList();
	}

	/**
	 * 字符串的拼接
	 * 
	 * @param <T>
	 * @param items
	 * @param classifier
	 * @return
	 */
	public static <T> String join(List<T> items, Function<T, String> classifier) {
		return items.stream().map(classifier).collect(Collectors.joining());
	}
	
	/**
	 * 字符串的拼接
	 * 
	 * @param <T>
	 * @param items
	 * @param classifier
	 * @return
	 */
	public static <T> String join(List<T> items, Function<T, String> classifier, String delimiter) {
		return items.stream().map(classifier).collect(Collectors.joining(delimiter));
	}

	/**
	 * 循环
	 * 
	 * @param <T>
	 * @param items
	 * @param classifier
	 * @return
	 */
	public static <T> List<T> each(List<T> items, Consumer<T> consumer) {
		items.stream().forEach(consumer);
		return items;
	}

	/**
	 * 循环
	 * 
	 * @param <T>
	 * @param items
	 * @param classifier
	 * @return
	 */
	public static <T> List<T> each(List<T> items, Predicate<T> filter, Consumer<T> consumer) {
		items.stream().filter(filter).forEach(consumer);
		return items;
	}

	/**
	 * 创建数据： 通过日期循环
	 * 
	 * @return
	 */
	public static <T> List<T> createByMonths(LocalDateTime beginMonth, LocalDateTime endMonth,
			Function<LocalDateTime, T> builder) {
		List<T> datas = Lists.newArrayList();
		LocalDateTime start = DateTimes.getMonthStart(beginMonth);
		LocalDateTime end = DateTimes.getMonthStart(endMonth);

		LocalDateTime month = start;
		while (!month.isAfter(end)) {
			datas.add(builder.apply(month));
			month = DateTimes.getDateByMonthOffset(month, 1);
		}
		return datas;
	}
}